/* Copyright (c) 2004-2008, Andriy Nikolov
 * All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.processmining.email;

import java.io.IOException;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.util.*;
import java.text.*;
import javax.xml.parsers.*;

/**
* <p>Parses the e-mail log file
 * @author Andriy Nikolov
 * @version 1.0
 */
public class EMailLogSaxParser extends DefaultHandler {

  static EMailMessage currentMessage = new EMailMessage();
  static EMailLog eMailLog;
  static String value;
  static String id;
  static String address;

  static boolean messageBeingSaved = false;
  static boolean charactersStarted = false;
  static String currentElement;

  static final int ELEMENT_NONE = 0;
  static final int ELEMENT_FROM = 1;
  static final int ELEMENT_TO = 2;
  static final int ELEMENT_CC = 3;
  static final int ELEMENT_BCC = 4;
  static final int ELEMENT_SUBJECT = 5;
  static final int ELEMENT_CASE = 6;
  static final int ELEMENT_TASK = 7;
  static final int ELEMENT_PHASE = 8;
  static final int ELEMENT_SENTON = 9;
  static final int ELEMENT_EMAILLOG = 10;
  static final int ELEMENT_MESSAGE = 11;
  static final int ELEMENT_ERROR = 12;



  public void setEMailLog(EMailLog log) {
    eMailLog = log;
  }

  public EMailLogSaxParser() {
    try {
      jbInit();
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  public EMailLogSaxParser(EMailLog log) {
    eMailLog = log;
  }

  public static void main(String[] argv) {
    eMailLog = new EMailLog();
    if (argv.length != 1) {
//      System.out.println("Usage: java untitled2.SaxParser1 [URI]");
      System.exit(0);
    }

    System.setProperty("javax.xml.parsers.SAXParserFactory",
                           "org.apache.xerces.jaxp.SAXParserFactoryImpl");

    String uri = argv[0];
    try {
        SAXParserFactory parserFactory = SAXParserFactory.newInstance();
        parserFactory.setValidating(false);
        parserFactory.setNamespaceAware(true);
        EMailLogSaxParser SaxParser1Instance = new EMailLogSaxParser();
        SAXParser parser = parserFactory.newSAXParser();
        parser.parse(uri, SaxParser1Instance);
    } catch (IOException exception) {
        exception.printStackTrace();
    } catch (SAXException exception) {
        exception.printStackTrace();
    } catch (ParserConfigurationException exception) {
        exception.printStackTrace();
    } catch (FactoryConfigurationError exception) {
        exception.printStackTrace();
    }
  }

  public void characters(char[] ch, int start, int length) throws SAXException {
    if (!messageBeingSaved)
      return;
    if (!charactersStarted) {
      value = new String(ch, start, length);
    } else {
      value = value + new String(ch, start, length);
    }
//    value = value.trim();
//    System.out.println("Value: "+value);
//    System.out.println("Start: "+start);
//    System.out.println("Length: "+length);

//    if((value.length()>0)&&(value.length()-start>length)) {
//      value = value.substring(start, length);
//    }
    charactersStarted = true;
  }
  public void endDocument() throws SAXException {
    /**@todo: Implement this endDocument method*/
//    throw new java.lang.UnsupportedOperationException("Method endDocument() not yet implemented.");
  }
  public void endElement(String uri, String localName, String qName) throws SAXException {
    EMailRecipient user;
    Date sentOn;
    DateFormat df;
    value = value.trim();
    if(messageBeingSaved) {
      if(currentElement.equals("From")) {
        user = eMailLog.createEMailRecipient(value, address);
        currentMessage.setFrom(user);
      }
      if(currentElement.equals("To")) {
        user = eMailLog.createEMailRecipient(value, address);
        currentMessage.addTo(user);
      }
      if(currentElement.equals("Cc")) {
        user = eMailLog.createEMailRecipient(value, address);
        currentMessage.addCc(user);
      }
      if(currentElement.equals("Bcc")) {
        user = eMailLog.createEMailRecipient(value, address);
        currentMessage.addBcc(user);
      }
      if(currentElement.equals("Subject")) {
          currentMessage.setSubject(value);
      }
      if(currentElement.equals("Case")) {
          currentMessage.setCase(value);
      }
      if(currentElement.equals("Task")) {
          currentMessage.setTask(value);
      }
      if(currentElement.equals("Phase")) {
          currentMessage.setPhase(value);
      }
      if(currentElement.equals("SentOn")) {
          df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.UK);
          try {
            if(value.indexOf(' ')==-1) {
              value = value.substring(0, 10)+" "+value.substring(10);
            }
            value = value.replace('/', '.');
            value = value.replace('-', '.');
            sentOn = df.parse(value);
            currentMessage.setSentOn(sentOn);
          }
          catch (ParseException pe) {
            try {
              value = value.replace('.', '/');
              value = value.replace('-', '/');
              sentOn = df.parse(value);
              currentMessage.setSentOn(sentOn);
            } catch(ParseException pe2) {
              try {
                value = value.replace('.', '-');
                value = value.replace('/', '-');
                sentOn = df.parse(value);
                currentMessage.setSentOn(sentOn);
              } catch(ParseException pe3) {
                pe3.printStackTrace();
              }
            }
          }
      }
    }

//    System.out.println("End: "+localName);
    if(messageBeingSaved) {
      if(localName.equals("Message")) {
        if(currentMessage.getFrom()==null) {
          user = eMailLog.createEMailRecipient("", "");
//          user.setActive(false);
          currentMessage.setFrom(user);
        }
        eMailLog.addMessage(currentMessage);
//        System.out.println("Saved");
        messageBeingSaved = false;
      }
    }
    currentElement = "None";
    address = "";
    charactersStarted = false;
  }

  public void setDocumentLocator(String target) {
    /**@todo: Implement this setDocumentLocator method*/
//    throw new java.lang.UnsupportedOperationException("Method setDocumentLocator() not yet implemented.");
  }
  public void startDocument() throws SAXException {
    /**@todo: Implement this startDocument method*/
//    throw new java.lang.UnsupportedOperationException("Method startDocument() not yet implemented.");
    eMailLog.createEMailRecipient("", "");
  }
  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//    System.out.println("Start element:"+localName);
    if (localName.equals("Message")) {
      id = attributes.getValue("messageId");
      if(!eMailLog.getMessageList().containsKey(id)) {
        messageBeingSaved = true;
        currentMessage = new EMailMessage();
        currentMessage.setId(id);
      } else {
        messageBeingSaved = false;
      }
    }
    if (messageBeingSaved) {
      currentElement = localName;
      if(currentElement.equals("To")||currentElement.equals("Cc")||currentElement.equals("Bcc"))
        address = attributes.getValue("address");
      if (address==null)
        address = "";
      charactersStarted = false;
    }
  }

  private void jbInit() throws Exception {
  }
}
